﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Microsoft.Win32;
using SccTools;

namespace StartTools
{
    public partial class Main : Form
    {
        [DllImport("user32.dll ")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        private const int SW_RESTORE = 9;
        public Main()
        {
            InitializeComponent();
            this.MaximizedBounds = Screen.PrimaryScreen.WorkingArea;
            //当用户试图注销或关闭系统时发生。  
            SystemEvents.SessionEnding += new SessionEndingEventHandler(SystemEvents_SessionEnding);
        }


        [DllImport("user32.dll")]
        public static extern bool ReleaseCapture();

        [DllImport("user32.dll")]



        public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
        private void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
        {
           e.Cancel = true;
        }



        /*
         
        //阻止自动关机
        protected override void WndProc(ref Message SystemMessage)
        {
            switch (SystemMessage.Msg)
            {
                case 0x0011:
                    SystemMessage.Result = (IntPtr)1;
                    break;
                default:
                    base.WndProc(ref SystemMessage);
                    break;
            }
        }
        
         */









private void openButton_Click(object sender, EventArgs e)
        {
            DataGridViewSelectedRowCollection rowCollection = path_dg.SelectedRows;
            if (rowCollection.Count>0)
            {
                foreach (DataGridViewRow row in rowCollection)
                {
                    DataGridViewCell cell = row.Cells[1];
                    string execPath = cell.Value.ToString();
                    if (!string.IsNullOrWhiteSpace(execPath))
                    {
                        try
                        {
                            System.Diagnostics.Process.Start(execPath);
                        }
                        catch (Exception exception)
                        {
                            MessageBox.Show($"出错了：{execPath}\n" + exception.Message);
                        }
                    }
                }
            }
        }        
        private void add_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Title = @"请选择文件或目录";
            DialogResult dialogResult = fileDialog.ShowDialog();
            if (dialogResult==DialogResult.OK)
            {
                int index = path_dg.Rows.Add();
                string fileDialogFileName = fileDialog.FileName;
                if (typeBuf.ContainsKey(fileDialogFileName))
                {
                    return;
                }
                DataGridViewRow dataGridViewRow = path_dg.Rows[index];
                dataGridViewRow.Selected = true;
                dataGridViewRow.Cells[0].Value = Path.GetFileNameWithoutExtension(fileDialogFileName);
                dataGridViewRow.Cells[1].Value = fileDialogFileName;
                typeBuf.Add(dataGridViewRow.Cells[1].Value.ToString(), dataGridViewRow.Cells[0].Value.ToString());
            }
        }

        private void delete_Click(object sender, EventArgs e)
        {
            if (path_dg.SelectedRows.Count>0)
            {
                string key = path_dg.SelectedRows[0].Cells[1].Value.ToString();
                path_dg.Rows.RemoveAt(path_dg.SelectedRows[0].Index);
                typeBuf.Remove(key);
            }
        }

        private void save_Click(object sender, EventArgs e)
        {
            saveData();
        }

        private void Main_Load(object sender, EventArgs e)
        { 
            LinkedList<string> linkedList = TextFileUtil.getTextLines();
            if (linkedList.Count>0)
            {
                foreach (string line in linkedList)
                {
                    string[] strings = line.Split('$');
                    typeBuf.Add(strings[1], strings[0]);
                    path_dg.Rows.Add(strings);
                }
            }
        }

        private static readonly string format = "{0}${1}";
        private void Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            saveData();
        }

        

        private void saveData()
        {
            List<string> linkedList = new List<string>();
            foreach (var keyValuePair in typeBuf)
            {
                linkedList.Add(string.Format(format, keyValuePair.Value, keyValuePair.Key));
            }

            linkedList.Sort();
            TextFileUtil.saveTextLines(linkedList);
            /*if (path_dg.Rows.Count > 0)
            {
                LinkedList<string> linkedList = new LinkedList<string>();
                *//*foreach (DataGridViewRow row in path_dg.Rows)
                {
                    linkedList.AddLast(string.Format(format, row.Cells[0].Value,row.Cells[1].Value));
                }*//*
                foreach (var keyValuePair in typeBuf)
                {
                    linkedList.AddLast(string.Format(format,keyValuePair.Value, keyValuePair.Key));
                }
                TextFileUtil.saveTextLines(linkedList);
            }*/
        }

        private void startOrForward_Click(object sender, EventArgs e)
        {
            DataGridViewSelectedRowCollection rowCollection = path_dg.SelectedRows;
            if (rowCollection.Count > 0)
            {
                DataGridViewRow row = rowCollection[0];
                DataGridViewCell cell = row.Cells[1];
                string execPath = cell.Value.ToString();
                if (!string.IsNullOrWhiteSpace(execPath)&&execPath.Contains(".exe "))
                {
                    try
                    {
                        //遍历进程列表查找目标程序是否运行运行则前置否则启动
                        Process[] pList = Process.GetProcesses(".");
                        /*foreach (Process p in pList)
                        {
                            if (p.MainModule != null && execPath.Equals(p.MainModule.FileName))
                            {
                                ShowWindow(p.MainWindowHandle, SW_RESTORE); //将窗口还原，如果不用此方法，缩小的窗口不能激活
                                SetForegroundWindow(p.MainWindowHandle);
                                return;
                            }
                        }*/

                        execPath = parseEvn(execPath);
                        string processPath = getProcessPath(execPath);
                        string pName = Path.GetFileNameWithoutExtension(processPath);
                        bool has = false;
                        foreach (Process p in pList)
                        {
                            if (p.ProcessName == pName)
                            {
                                ShowWindow(p.MainWindowHandle, SW_RESTORE); //将窗口还原，如果不用此方法，缩小的窗口不能激活
                                SetForegroundWindow(p.MainWindowHandle);
                                has = true;
                            }
                        }

                        if (!has)
                        {
                            System.Diagnostics.Process process = new System.Diagnostics.Process();
                            process.StartInfo.FileName = processPath;
                            process.StartInfo.Arguments = execPath.Replace(processPath,"");
                            process.Start();
                            //System.Diagnostics.Process.Start(execPath);
                        }

                    }
                    catch (Exception exception)
                    {
                        MessageBox.Show($"出错了：{execPath}\n" + exception.Message);
                    }

                    /*string fileFullPath = @"D:\Temp\aa.txt";

                    string fileName = Path.GetFileName(fileFullPath);  //aa.txt
                    string fileNameNoExt = Path.GetFileNameWithoutExtension(fileFullPath);  //aa
                    string fileExt = Path.GetExtension(fileFullPath);  //.txt

                    string filePathOnly = Path.GetDirectoryName(fileFullPath);  //D:\Temp
                    string folderName = Path.GetFileName(filePathOnly);  //Temp*/
                }
                else
                {
                    try
                    {
                        Process.Start(execPath);
                    }
                    catch(Exception exception) 
                    {
                        MessageBox.Show(exception.Message);
                    }
                    
                }
            }
        }

        private string getProcessPath(string execPath)
        {
            execPath = execPath.Substring(0, execPath.IndexOf(".exe ")+4);
            return execPath;
        }

        private static Regex regex = new Regex(@"%[\w]*%");
        private string parseEvn(string path)
        {
            foreach (Match match in regex.Matches(path))
            {
                string matchStr = match.Value.ToString();
                string evnName = matchStr.Replace("%", "");
                string str = Environment.GetEnvironmentVariable(evnName);
                path = path.Replace(matchStr, str);
            }
            return path;
        }

        private void label1_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void label3_Click(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Maximized)
            {
                this.WindowState = FormWindowState.Normal;
            }
            else
            {
                this.WindowState = FormWindowState.Maximized;
            }
        }

        private void label2_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            DataGridViewSelectedRowCollection rowCollection = path_dg.SelectedRows;
            if (rowCollection.Count > 0)
            {
                DataGridViewRow row = rowCollection[0];
                DataGridViewCell cell = row.Cells[1];
                string execPath = cell.Value.ToString();
                FileInfo fi = new FileInfo(execPath);
                if ((fi.Attributes & FileAttributes.Directory) != 0)
                {
                    Process.Start(execPath);
                }
                else
                {
                    if (fi.DirectoryName != null) Process.Start(fi.DirectoryName);
                }
            }
        }

        private void path_dg_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            startOrForward_Click(sender,e);
        }

        private void kill_Click(object sender, EventArgs e)
        {
            reload();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            startOrForward_Click(sender, e);
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            string sText = textBox1.Text;
            path_dg.Rows.Clear();
            if (string.IsNullOrWhiteSpace(sText))
            {
                addAll();
            }
            else
            {
                addPart(sText);
            }
            
        }
        private void addAll()
        {
            List<string[]> re = new List<string[]>();
            foreach (var keyValuePair in typeBuf)
            {
                re.Add(new[] { keyValuePair.Value, keyValuePair.Key });
            }
            foreach (var data in re)
            {
                path_dg.Rows.Add(data);
            }
        }

        private void addPart(string sText)
        {
            sText = sText.ToLower();
            List<string[]> re = new List<string[]>();
            foreach (var keyValuePair in typeBuf)
            {
                if (keyValuePair.Key.ToLower().Contains(sText) || keyValuePair.Value.ToLower().Contains(sText))
                {
                    re.Add(new[] { keyValuePair.Value, keyValuePair.Key });
                }
            }
            foreach (var data in re)
            {
                path_dg.Rows.Add(data);
            }
        }

        private Dictionary<string, string> typeBuf = new Dictionary<string, string>();

        private void addByWindow_Click(object sender, EventArgs e)
        {
            new AddOrUpdate(addRow).ShowDialog();
        }

        public void addRow(string title, string path)
        {
            if (typeBuf.ContainsKey(path))
            {
                updateAndReload(title, path);
                return;
            }
            int index = path_dg.Rows.Add();
            DataGridViewRow dataGridViewRow = path_dg.Rows[index];
            dataGridViewRow.Selected = true;
            dataGridViewRow.Cells[0].Value = title;
            dataGridViewRow.Cells[1].Value = path;
            typeBuf.Add(dataGridViewRow.Cells[1].Value.ToString(), dataGridViewRow.Cells[0].Value.ToString());
        }

        private void editByWindow_Click(object sender, EventArgs e)
        {
            DataGridViewSelectedRowCollection rowCollection = path_dg.SelectedRows;
            if (rowCollection.Count > 0)
            {
                DataGridViewRow row = rowCollection[0];
                DataGridViewCell cell_path = row.Cells[1];
                DataGridViewCell cell_title = row.Cells[0];
                string execPath = cell_path.Value.ToString();
                string execTitle = cell_title.Value.ToString();
                new AddOrUpdate(addRow, execTitle, execPath).ShowDialog();
            }
        }

        public void updateAndReload(string title,string path)
        {
            typeBuf.Remove(path);
            typeBuf.Add(path, title);
            reload();
        }

        private void reload()
        {
            path_dg.Rows.Clear();
            typeBuf = typeBuf.OrderBy(i => i.Value).ToDictionary(p => p.Key, o => o.Value);
            addAll();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            textBox1.Text = "";
        }

        private void FrmMain_MouseDown(object sender, MouseEventArgs e)
        {
            
        }
    }
}
